<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!--

Generated from t-y-scheme.tex by tex2page, v 20070609
(running on MzScheme 4.2.1, unix), 
(c) Dorai Sitaram, 
http://www.ccs.neu.edu/~dorai/tex2page/tex2page-doc.html

-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>
Teach Yourself Scheme in Fixnum Days 中文版
</title>
<link rel="stylesheet" type="text/css" href="t-y-scheme-Z-S.css" title=default>
<meta name="robots" content="index,follow">
<meta name=description content="A practical
introduction to the programming language Scheme">

<meta name=author content="Dorai Sitaram">

<link rev=made href="mailto:dorai @ ccs.neu.edu">
</head>
<body>
<div id=slidecontent>
<div align=right class=navigation>[Go to <span><a href="t-y-scheme.html">first</a>, <a href="t-y-scheme-Z-H-19.html">previous</a></span><span>, <a href="t-y-scheme-Z-H-21.html">next</a></span> page<span>; &nbsp;&nbsp;</span><span><a href="t-y-scheme-Z-H-1.html#node_toc_start">contents</a></span><span><span>; &nbsp;&nbsp;</span><a href="t-y-scheme-Z-H-25.html#node_index_start">index</a></span>]</div>
<p></p>
<a name="node_chap_A"></a>
<h1 class=chapter>
<div class=chapterheading><a href="t-y-scheme-Z-H-1.html#node_toc_node_chap_A">Appendix A</a></div><br>
<a href="t-y-scheme-Z-H-1.html#node_toc_node_chap_A">Scheme dialects</a></h1>
<p></p>
<p>
<a name="node_idx_488"></a><a name="node_idx_490"></a>All major Scheme dialects implement the R5RS
specification [<a href="t-y-scheme-Z-H-24.html#node_bib_23">23</a>].  By using only the features
documented in the R5RS, one can write Scheme code that
is portable across the dialects.  However, the R5RS,
either for want of consensus or because of inevitable
system dependencies, remains silent on several matters
that non-trivial programming cannot ignore.  The
various dialects have therefore had to solve these
matters in a non-standard and idiosyncratic manner.</p>
<p>
<a name="node_idx_492"></a></p>
<p>
This book uses the MzScheme [<a href="t-y-scheme-Z-H-24.html#node_bib_9">9</a>]
dialect of Scheme, and thereby uses several
features that are nonstandard.  The complete
list of the dialect-dependent features used
in this book is: the command-line (both for
opening a listener session and for shell scripts),
<code class=scheme><span class=keyword>define-macro</span></code>, <code class=scheme><span class=variable>delete-file</span></code>, <code class=scheme><span class=variable>file-exists?</span></code>,
<code class=scheme><span class=variable>file-or-directory-modify-seconds</span></code>, <code class=scheme><span class=keyword>fluid-let</span></code>,
<code class=scheme><span class=variable>gensym</span></code>, <code class=scheme><span class=variable>getenv</span></code>, <code class=scheme><span class=variable>get-output-string</span></code>,
<code class=scheme><span class=variable>load-relative</span></code>, <code class=scheme><span class=variable>open-input-string</span></code>,
<code class=scheme><span class=variable>open-output-string</span></code>, <code class=scheme><span class=variable>read-line</span></code>, <code class=scheme><span class=variable>reverse!</span></code>,
<code class=scheme><span class=variable>system</span></code>,  <code class=scheme><span class=keyword>unless</span></code> and <code class=scheme><span class=keyword>when</span></code>.</p>
<p>
All but two of these  
are present in the default environment of MzScheme.  The missing two,
<code class=scheme><span class=keyword>define-macro</span></code> and <code class=scheme><span class=variable>system</span></code>, are provided in
standard MzScheme libraries, which can be explicitly loaded into
MzScheme using the forms:</p>
<p>
</p>
<pre class=scheme>(<span class=variable>require</span> (<span class=variable>lib</span> <span class=selfeval>&quot;defmacro.ss&quot;</span>)) <span class=comment>;provides define-macro</span>
(<span class=variable>require</span> (<span class=variable>lib</span> <span class=selfeval>&quot;process.ss&quot;</span>))  <span class=comment>;provides system</span>
</pre><p> </p>
<p>
</p>

<p class=noindent>A good place to place these forms is the MzScheme
<em>initialization file</em> (or <em>init file</em>), which, on Unix, is the file
<code class=verbatim>.mzschemerc</code> in the user&#8217;s home directory.<a name="node_call_footnote_Temp_13"></a><sup><small><a href="#node_footnote_Temp_13">1</a></small></sup>  </p>
<p>
Some of the nonstandard features (eg, <code class=scheme><span class=variable>file-exists?</span></code>,
<code class=scheme><span class=variable>delete-file</span></code>) are in fact de facto standards and are present
in many Schemes.  Some other features (eg, <code class=scheme><span class=keyword>when</span></code>,
<code class=scheme><span class=keyword>unless</span></code>) have more or less &#8220;plug-in&#8221; definitions
(given in this book) that can be loaded into any Scheme
dialect that doesn&#8217;t have them primitively.  The rest
require a dialect-specific definition
(eg, <code class=scheme><span class=variable>load-relative</span></code>).</p>
<p>
This chapter describes how to incorporate into your
Scheme dialect the nonstandard features used in this
book.  For further detail about your Scheme
dialect, consult the documentation provided by its
implementor (appendix <a href="t-y-scheme-Z-H-24.html#node_chap_E">E</a>).</p>
<p>
</p>
<p>
<a name="node_idx_494"></a></p>
<p>
</p>
<a name="node_sec_A.1"></a>
<h2 class=section><a href="t-y-scheme-Z-H-1.html#node_toc_node_sec_A.1">A.1&nbsp;&nbsp;Invocation and init files</a></h2>
<p><a name="node_idx_496"></a><a name="node_idx_498"></a></p>
<p>
Like MzScheme, many Scheme dialects load, if
available, an init file, usually supplied in the user&#8217;s
home directory.  The init file is a convenient location
in which to place definitions for nonstandard features.
Eg, the nonstandard procedure
<code class=scheme><span class=variable>file-or-directory-modify-seconds</span></code> can be added to
the Guile&nbsp;[<a href="t-y-scheme-Z-H-24.html#node_bib_13">13</a>] dialect of Scheme by putting the
following code in Guile&#8217;s init file, which is
<code class=verbatim>~/.guile</code>:</p>
<p>
</p>
<pre class=scheme>(<span class=keyword>define</span> <span class=variable>file-or-directory-modify-seconds</span>
  (<span class=keyword>lambda</span> (<span class=variable>f</span>)
    (<span class=variable>vector-ref</span> (<span class=variable>stat</span> <span class=variable>f</span>) <span class=selfeval>9</span>)))
</pre><p></p>
<p>
Also, the various Scheme dialects have their own
distinctively named commands to invoke their respective
listeners.  The following
table lists the invoking commands and init files
for some Scheme dialects:</p>
<p>
</p>
<table><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<em>Dialect name</em>  </td><td>   <em>Command</em>  </td><td>   <em>Init&nbsp;file</em>  </td></tr>
<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Bigloo  </td><td>   <code class=verbatim>bigloo</code>  </td><td>   <code class=verbatim>~/.bigloorc</code>  </td></tr>
<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Chicken  </td><td>   <code class=verbatim>csi</code>  </td><td>   <code class=verbatim>~/.csirc</code>  </td></tr>
<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gambit  </td><td>   <code class=verbatim>gsi</code>  </td><td>   <code class=verbatim>~/gambc.scm</code>  </td></tr>
<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gauche  </td><td>   <code class=verbatim>gosh</code>  </td><td>   <code class=verbatim>~/.gaucherc</code>  </td></tr>
<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Guile  </td><td>   <code class=verbatim>guile</code>  </td><td>   <code class=verbatim>~/.guile</code>  </td></tr>
<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Kawa  </td><td>   <code class=verbatim>kawa</code>  </td><td>   <code class=verbatim>~/.kawarc.scm</code>  </td></tr>
<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MIT Scheme (Unix)  </td><td>   <code class=verbatim>scheme</code>  </td><td>   <code class=verbatim>~/.scheme.init</code>  </td></tr>
<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MIT Scheme (Win)  </td><td>   <code class=verbatim>scheme</code>  </td><td>   <code class=verbatim>~/scheme.ini</code>  </td></tr>
<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MzScheme (Unix, Mac OS X)  </td><td>   <code class=verbatim>mzscheme</code>  </td><td>    <code class=verbatim>~/.mzschemerc</code>  </td></tr>
<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MzScheme (Win, Mac OS Classic)  </td><td>   <code class=verbatim>mzscheme</code>  </td><td>   <code class=verbatim>~/mzschemerc.ss</code>  </td></tr>
<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SCM  </td><td>   <code class=verbatim>scm</code>  </td><td>   <code class=verbatim>~/ScmInit.scm</code>  </td></tr>
<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STk  </td><td>   <code class=verbatim>snow</code>  </td><td>   <code class=verbatim>~/.stkrc</code>  </td></tr>
</table><p></p>
<p>
</p>
<p>
<a name="node_idx_500"></a></p>
<p>
</p>
<a name="node_sec_A.2"></a>
<h2 class=section><a href="t-y-scheme-Z-H-1.html#node_toc_node_sec_A.2">A.2&nbsp;&nbsp;Shell scripts</a></h2>
<p>The initial line for a shell script written in Guile is:</p>
<p>
</p>
<pre class=scheme><span class=selfeval>&quot;:&quot;</span><span class=comment>;exec guile -s $0 &quot;$@&quot;</span>
</pre><p></p>
<p>
In the script, the procedure-call <code class=scheme>(<span class=variable>command-line</span>)</code> returns
the list of the script&#8217;s name and arguments.  To access
just the arguments, take the <code class=scheme><span class=variable>cdr</span></code> of this list.</p>
<p>
A Gauche&nbsp;[<a href="t-y-scheme-Z-H-24.html#node_bib_21">21</a>] shell script starts out as:</p>
<p>
</p>
<pre class=scheme><span class=selfeval>&quot;:&quot;</span><span class=comment>; exec gosh -- $0 &quot;$@&quot;</span>
</pre><p></p>
<p>
In the script, the variable <code class=scheme><span class=global>*argv*</span></code> holds 
the list of the script&#8217;s arguments.</p>
<p>
A shell script written in SCM starts out as:</p>
<p>
</p>
<pre class=scheme><span class=selfeval>&quot;:&quot;</span><span class=comment>;exec scm -l $0 &quot;$@&quot;</span>
</pre><p></p>
<p>
In the script, the variable <code class=scheme><span class=global>*argv*</span></code> contains
the list of the Scheme executable name, the script&#8217;s
name, the option <code class=verbatim>-l</code>, and the script&#8217;s arguments.
To
access just the arguments, take the <code class=scheme><span class=variable>cdddr</span></code> of this list.</p>
<p>
STk&nbsp;[<a href="t-y-scheme-Z-H-24.html#node_bib_14">14</a>] shell scripts start out as:</p>
<p>
</p>
<pre class=scheme><span class=selfeval>&quot;:&quot;</span><span class=comment>;exec snow -f $0 &quot;$@&quot;</span>
</pre><p></p>
<p>
In the script, the variable <code class=scheme><span class=global>*argv*</span></code> contains
the list of the script&#8217;s arguments.</p>
<p>
<a name="node_idx_502"></a></p>
<p>
</p>
<a name="node_sec_A.3"></a>
<h2 class=section><a href="t-y-scheme-Z-H-1.html#node_toc_node_sec_A.3">A.3&nbsp;&nbsp;<code class=scheme><span class=keyword>define-macro</span></code></a></h2>
<p></p>
<p>
<a name="node_idx_504"></a><a name="node_idx_506"></a><a name="node_idx_508"></a><a name="node_idx_510"></a><a name="node_idx_512"></a>The <code class=scheme><span class=keyword>define-macro</span></code> used in the text occurs in
the Scheme dialects Bigloo [<a href="t-y-scheme-Z-H-24.html#node_bib_30">30</a>],
Chicken&nbsp;[<a href="t-y-scheme-Z-H-24.html#node_bib_32">32</a>], Gambit
[<a href="t-y-scheme-Z-H-24.html#node_bib_6">6</a>], Gauche&nbsp;[<a href="t-y-scheme-Z-H-24.html#node_bib_21">21</a>], Guile, MzScheme and Pocket Scheme
[<a href="t-y-scheme-Z-H-24.html#node_bib_15">15</a>].  There are minor variations in
how macros are defined in the other Scheme dialects.
The rest of this section will point out how these
other dialects notate the following code fragment:</p>
<p>
</p>
<pre class=scheme>(<span class=keyword>define-macro</span> <span class=variable>MACRO-NAME</span>
  (<span class=keyword>lambda</span> <span class=variable>MACRO-ARGS</span>
    <span class=variable>MACRO-BODY</span> ...))
</pre><p></p>
<p>
<a name="node_idx_514"></a></p>
<p>
</p>

<p class=noindent>In MIT Scheme&nbsp;[<a href="t-y-scheme-Z-H-24.html#node_bib_26">26</a>] version 7.7.1 and later, this is written as:</p>
<p>
</p>
<pre class=scheme>(<span class=keyword>define-syntax</span> <span class=variable>MACRO-NAME</span>
  (<span class=variable>rsc-macro-transformer</span>
    (<span class=keyword>let</span> ((<span class=variable>xfmr</span> (<span class=keyword>lambda</span> <span class=variable>MACRO-ARGS</span> <span class=variable>MACRO-BODY</span> ...)))
      (<span class=keyword>lambda</span> (<span class=variable>e</span> <span class=variable>r</span>)
        (<span class=variable>apply</span> <span class=variable>xfmr</span> (<span class=variable>cdr</span> <span class=variable>e</span>))))))
</pre><p></p>
<p>
</p>

<p class=noindent>In older versions of MIT Scheme:</p>
<p>
</p>
<pre class=scheme>(<span class=variable>syntax-table-define</span> <span class=variable>system-global-syntax-table</span> <span class=keyword>'</span><span class=variable>MACRO-NAME</span>
  (<span class=variable>macro</span> <span class=variable>MACRO-ARGS</span>
    <span class=variable>MACRO-BODY</span> ...))
</pre><p></p>
<p>
<a name="node_idx_516"></a><a name="node_idx_518"></a></p>
<p>
</p>

<p class=noindent>In SCM&nbsp;[<a href="t-y-scheme-Z-H-24.html#node_bib_20">20</a>]  and Kawa [<a href="t-y-scheme-Z-H-24.html#node_bib_3">3</a>]:</p>
<p>
</p>
<pre class=scheme>(<span class=keyword>defmacro</span> <span class=variable>MACRO-NAME</span> <span class=variable>MACRO-ARGS</span>
  <span class=variable>MACRO-BODY</span> ...)
</pre><p></p>
<p>
<a name="node_idx_520"></a></p>
<p>
</p>

<p class=noindent>In STk&nbsp;[<a href="t-y-scheme-Z-H-24.html#node_bib_14">14</a>]: </p>
<p>
</p>
<pre class=scheme>(<span class=keyword>define-macro</span> (<span class=variable>MACRO-NAME</span> . <span class=variable>MACRO-ARGS</span>)
  <span class=variable>MACRO-BODY</span> ...)
</pre><p></p>
<p>
<a name="node_idx_522"></a></p>
<p>
</p>
<a name="node_sec_A.4"></a>
<h2 class=section><a href="t-y-scheme-Z-H-1.html#node_toc_node_sec_A.4">A.4&nbsp;&nbsp;<code class=scheme><span class=variable>load-relative</span></code></a></h2>
<p>The procedure <code class=scheme><span class=variable>load-relative</span></code> may be defined for Guile as follows:</p>
<p>
</p>
<pre class=scheme>(<span class=keyword>define</span> <span class=variable>load-relative</span>
  (<span class=keyword>lambda</span> (<span class=variable>f</span>)
    (<span class=keyword>let*</span> ((<span class=variable>n</span> (<span class=variable>string-length</span> <span class=variable>f</span>))
           (<span class=variable>full-pathname?</span>
             (<span class=keyword>and</span> (<span class=variable>&gt;</span> <span class=variable>n</span> <span class=selfeval>0</span>)
                  (<span class=keyword>let</span> ((<span class=variable>c0</span> (<span class=variable>string-ref</span> <span class=variable>f</span> <span class=selfeval>0</span>)))
                    (<span class=keyword>or</span> (<span class=variable>char=?</span> <span class=variable>c0</span> <span class=selfeval>#\/</span>)
                        (<span class=variable>char=?</span> <span class=variable>c0</span> <span class=selfeval>#\~</span>))))))
      (<span class=variable>basic-load</span>
        (<span class=keyword>if</span> <span class=variable>full-pathname?</span> <span class=variable>f</span>
            (<span class=keyword>let</span> ((<span class=variable>clp</span> (<span class=variable>current-load-port</span>)))
              (<span class=keyword>if</span> <span class=variable>clp</span>
                  (<span class=variable>string-append</span>
                    (<span class=variable>dirname</span> (<span class=variable>port-filename</span> <span class=variable>clp</span>)) <span class=selfeval>&quot;/&quot;</span> <span class=variable>f</span>)
                  <span class=variable>f</span>)))))))
</pre><p></p>
<p>
For SCM:</p>
<p>
</p>
<pre class=scheme>(<span class=keyword>define</span> <span class=variable>load-relative</span>
  (<span class=keyword>lambda</span> (<span class=variable>f</span>)
    (<span class=keyword>let*</span> ((<span class=variable>n</span> (<span class=variable>string-length</span> <span class=variable>f</span>))
           (<span class=variable>full-pathname?</span>
            (<span class=keyword>and</span> (<span class=variable>&gt;</span> <span class=variable>n</span> <span class=selfeval>0</span>)
                 (<span class=keyword>let</span> ((<span class=variable>c0</span> (<span class=variable>string-ref</span> <span class=variable>f</span> <span class=selfeval>0</span>)))
                   (<span class=keyword>or</span> (<span class=variable>char=?</span> <span class=variable>c0</span> <span class=selfeval>#\/</span>)
                       (<span class=variable>char=?</span> <span class=variable>c0</span> <span class=selfeval>#\~</span>))))))
    (<span class=variable>load</span> (<span class=keyword>if</span> (<span class=keyword>and</span> <span class=global>*load-pathname*</span> <span class=variable>full-pathname?</span>)
              (<span class=variable>in-vicinity</span> (<span class=variable>program-vicinity</span>) <span class=variable>f</span>)
              <span class=variable>f</span>)))))
</pre><p></p>
<p>
For STk, the following definition for <code class=scheme><span class=variable>load-relative</span></code>
works only if you discipline yourself to not use <code class=scheme><span class=variable>load</span></code>:</p>
<p>
</p>
<pre class=scheme>(<span class=keyword>define</span> <span class=global>*load-pathname*</span> <span class=selfeval>#f</span>)

(<span class=keyword>define</span> <span class=variable>stk%load</span> <span class=variable>load</span>)

(<span class=keyword>define</span> <span class=variable>load-relative</span>
  (<span class=keyword>lambda</span> (<span class=variable>f</span>)
    (<span class=keyword>fluid-let</span> ((<span class=global>*load-pathname*</span>
                  (<span class=keyword>if</span> (<span class=variable>not</span> <span class=global>*load-pathname*</span>) <span class=variable>f</span>
                      (<span class=keyword>let*</span> ((<span class=variable>n</span> (<span class=variable>string-length</span> <span class=variable>f</span>))
                             (<span class=variable>full-pathname?</span>
                               (<span class=keyword>and</span> (<span class=variable>&gt;</span> <span class=variable>n</span> <span class=selfeval>0</span>)
                                    (<span class=keyword>let</span> ((<span class=variable>c0</span> (<span class=variable>string-ref</span> <span class=variable>f</span> <span class=selfeval>0</span>)))
                                      (<span class=keyword>or</span> (<span class=variable>char=?</span> <span class=variable>c0</span> <span class=selfeval>#\/</span>)
                                          (<span class=variable>char=?</span> <span class=variable>c0</span> <span class=selfeval>#\~</span>))))))
                        (<span class=keyword>if</span> <span class=variable>full-pathname?</span> <span class=variable>f</span>
                            (<span class=variable>string-append</span>
                              (<span class=variable>dirname</span> <span class=global>*load-pathname*</span>)
                              <span class=selfeval>&quot;/&quot;</span> <span class=variable>f</span>))))))
      (<span class=variable>stk%load</span> <span class=global>*load-pathname*</span>))))

(<span class=keyword>define</span> <span class=variable>load</span>
  (<span class=keyword>lambda</span> (<span class=variable>f</span>)
    (<span class=variable>error</span> <span class=selfeval>&quot;Don't use load.  Use load-relative instead.&quot;</span>)))
</pre><p>
</p>
<p>
</p>
<div class=footnoterule><hr></div><p></p>
<div class=footnote><p><a name="node_footnote_Temp_13"></a><sup><small><a href="#node_call_footnote_Temp_13">1</a></small></sup> We will
use <code class=verbatim>~/filename</code> to denote the file called
<code class=verbatim>filename</code> in the user&#8217;s home directory.</p>
</div>
<div class=smallskip></div>
<p style="margin-top: 0pt; margin-bottom: 0pt">
<div align=right class=navigation>[Go to <span><a href="t-y-scheme.html">first</a>, <a href="t-y-scheme-Z-H-19.html">previous</a></span><span>, <a href="t-y-scheme-Z-H-21.html">next</a></span> page<span>; &nbsp;&nbsp;</span><span><a href="t-y-scheme-Z-H-1.html#node_toc_start">contents</a></span><span><span>; &nbsp;&nbsp;</span><a href="t-y-scheme-Z-H-25.html#node_index_start">index</a></span>]</div>
</p>
<p></p>
</div>
</body>
</html>
